package cn.com.wangluotongxin.member.service.impl;

import cn.com.wangluotongxin.admin.model.constants.YesNo;
import cn.com.wangluotongxin.common.constants.CommonConstant;
import cn.com.wangluotongxin.common.pojo.LoginUser;
import cn.com.wangluotongxin.common.utils.AuthTokenUtil;
import cn.com.wangluotongxin.common.utils.XXTeaUtil;
import cn.com.wangluotongxin.member.event.MemberLoginPushEvent;
import cn.com.wangluotongxin.member.event.MemberRegisterPushEvent;
import cn.com.wangluotongxin.member.event.MemberUpdatePushEvent;
import cn.com.wangluotongxin.member.event.pojo.MemberLoginPojo;
import cn.com.wangluotongxin.member.event.pojo.MemberRegisterPojo;
import cn.com.wangluotongxin.member.event.pojo.MemberUpdatePojo;
import cn.com.wangluotongxin.member.form.MemberInfoAuthForm;
import cn.com.wangluotongxin.member.form.MemberInfoRegisterForm;
import cn.com.wangluotongxin.member.form.MemberInfoUpdateForm;
import cn.com.wangluotongxin.member.model.MemberInfo;
import cn.com.wangluotongxin.member.mapper.MemberInfoMapper;
import cn.com.wangluotongxin.member.model.constants.EnabledStatus;
import cn.com.wangluotongxin.member.service.IMemberInfoService;
import cn.com.wangluotongxin.member.vo.MemberCheckPhoneVo;
import cn.com.wangluotongxin.member.vo.MemberInfoVo;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

/**
 * <p>
 * 网络通信-用户信息 服务实现类
 * </p>
 *
 * @author AutoGenerator
 * @since 2024-11-23
 */
@Service
public class MemberInfoServiceImpl extends ServiceImpl<MemberInfoMapper, MemberInfo> implements IMemberInfoService {

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public String getToken(String username, String password) {
        MemberInfo memberInfo = this.getOne(new LambdaQueryWrapper<MemberInfo>()
                .eq(MemberInfo::getUsername, username)
                .last("limit 0,1"));
        Assert.notNull(memberInfo, "账号不存在");
        Assert.isTrue(memberInfo.getIsEnabled().equals(EnabledStatus.ENABLED.getCode()), "账号被禁用");
        Assert.isTrue(memberInfo.getPassword().equals(XXTeaUtil.encrypt(password)), "密码错误");
        return this.getUserToken(memberInfo);
    }

    @Override
    public String getToken(String phone) {
        MemberInfo memberInfo = this.getOne(new LambdaQueryWrapper<MemberInfo>()
                .eq(MemberInfo::getPhone, phone)
                .last("limit 0,1"));
        Assert.notNull(memberInfo, "账号不存在");
        Assert.isTrue(memberInfo.getIsEnabled().equals(EnabledStatus.ENABLED.getCode()), "账号被禁用");
        return this.getUserToken(memberInfo);
    }

    @Override
    public MemberInfoVo getInfo(Integer memberId) {
        return baseMapper.getInfo(memberId);
    }

    @Override
    public void updateInfo(MemberInfoUpdateForm form, LoginUser loginUser) {
        LambdaUpdateWrapper<MemberInfo> updateWrapper = new LambdaUpdateWrapper<MemberInfo>();
        MemberUpdatePojo pojo = new MemberUpdatePojo();
        pojo.setId(loginUser.getId());
        if(StrUtil.isNotBlank(form.getPhone())) {
            updateWrapper.set(MemberInfo::getPhone, form.getPhone());
            pojo.setPhone(form.getPhone());
        }
        if(StrUtil.isNotBlank(form.getPassword())) {
            updateWrapper.set(MemberInfo::getPassword, XXTeaUtil.encrypt(form.getPassword()));
        }
        if(StrUtil.isNotBlank(form.getHeadImg())) {
            updateWrapper.set(MemberInfo::getHeadImg, form.getHeadImg());
            pojo.setHeadImg(form.getHeadImg());
        }
        if(StrUtil.isNotBlank(form.getPhone()) || StrUtil.isNotBlank(form.getPassword()) || StrUtil.isNotBlank(form.getHeadImg())) {
            updateWrapper.eq(MemberInfo::getId, loginUser.getId());
            this.update(updateWrapper);
            applicationEventPublisher.publishEvent(new MemberUpdatePushEvent(this, pojo));
        }
    }

    @Override
    public void register(MemberInfoRegisterForm form) {
        MemberInfo memberInfo = new MemberInfo();
        BeanUtils.copyProperties(form, memberInfo);
        memberInfo.setPassword(XXTeaUtil.encrypt(form.getPassword()));
        memberInfo.setUsername(this.buildUsername(form.getPhone()));
        this.save(memberInfo);
        MemberRegisterPojo pojo = new MemberRegisterPojo()
                .setId(memberInfo.getId())
                .setUsername(memberInfo.getUsername())
                .setName(memberInfo.getName())
                .setIdCard(memberInfo.getIdCard())
                .setPhone(memberInfo.getPhone())
                .setHeadImg(memberInfo.getHeadImg());
        applicationEventPublisher.publishEvent(new MemberRegisterPushEvent(this, pojo));
    }

    @Override
    public void memberAuth(MemberInfoAuthForm form, Integer memberId) {
        this.update(new LambdaUpdateWrapper<MemberInfo>()
                .set(MemberInfo::getName, form.getName())
                .set(MemberInfo::getIdCard, form.getIdCard())
                .eq(MemberInfo::getId, memberId));

        MemberUpdatePojo pojo = new MemberUpdatePojo()
                .setId(memberId)
                .setName(form.getName())
                .setIdCard(form.getIdCard());
        applicationEventPublisher.publishEvent(new MemberUpdatePushEvent(this, pojo));
    }

    @Override
    public void logout(Integer memberId) {
        MemberInfo memberInfo = this.getById(memberId);
        // 退出登录通知
        applicationEventPublisher.publishEvent(new MemberLoginPushEvent(this, new MemberLoginPojo()
                .setId(memberInfo.getId())
                .setUsername(memberInfo.getUsername())
                .setOnlineStatus(YesNo.YES.getCode())
                .setPhone(memberInfo.getPhone())));
    }

    @Override
    public MemberCheckPhoneVo checkPhone(String phone) {
        Boolean isExist = false;
        if(this.count(new LambdaQueryWrapper<MemberInfo>()
                .eq(MemberInfo::getPhone, phone)) > 0) {
            isExist = true;
        }
        return new MemberCheckPhoneVo().setPhone(phone).setIsExist(isExist);
    }

    private String buildUsername(String phone) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(DateUtil.format(DateUtil.date(), "yyyyMMdd"));
        stringBuilder.append(phone.substring(7, 11));
        stringBuilder.append(RandomUtil.randomNumbers(4));
        return stringBuilder.toString();
    }

    private String getUserToken(MemberInfo memberInfo) {
        LoginUser loginUser = new LoginUser();
        loginUser.setId(memberInfo.getId());
        loginUser.setUsername(memberInfo.getUsername());
        loginUser.setName(memberInfo.getName());
        this.update(new LambdaUpdateWrapper<MemberInfo>()
                .set(MemberInfo::getLastLoginTime, DateUtil.date())
                .eq(MemberInfo::getId, memberInfo.getId()));
        // 登录通知
        applicationEventPublisher.publishEvent(new MemberLoginPushEvent(this, new MemberLoginPojo()
                .setId(memberInfo.getId())
                .setUsername(memberInfo.getUsername())
                .setOnlineStatus(YesNo.YES.getCode())
                .setPhone(memberInfo.getPhone())));
        return AuthTokenUtil.create(loginUser).build(30);
    }
}
